﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using Library.OrmEnterpriseEntity.Factor;

namespace Library.OrmEnterpriseEntity {
	/// <summary>
	/// Perform SQL statement by command text or store procedure
	/// </summary>
	public class SqlStatement {
		/// <summary>
		/// Create SqlStatement instance
		/// </summary>
		/// <param name="commandText">command text or store procedure name</param>
		/// <exception cref="ArgumentNullException">Thow when commandType is null or emplty</exception>
		public SqlStatement(string commandText)
			: this() {
			if (String.IsNullOrEmpty(commandText)) throw new ArgumentNullException("commandText");
			CommandText = commandText;

		}
		/// <summary>
		/// Create SqlStatement instance
		/// </summary>
		/// <param name="commandText">command text or store procedure name</param>
		/// <param name="parameter"></param>
		/// <exception cref="ArgumentNullException">Thow when commandType is null or emplty, or parameter is null</exception>
		public SqlStatement(string commandText, QueryParameter parameter)
			: this(commandText) {
			AddParameter(parameter);
		}
		private SqlStatement() {
			Parameters = new List<QueryParameter>();
			CommandType = CommandType.Text;
		}
		/// <summary>
		/// Get command text
		/// </summary>
		public string CommandText { get; private set; }
		/// <summary>
		/// Get command type, default is Text
		/// </summary>
		public CommandType CommandType { get; private set; }
		/// <summary>
		/// Set commandtType
		/// </summary>
		/// <param name="commandType"></param>
		/// <returns>SqlStatement</returns>
		public SqlStatement SetCommandType(CommandType commandType) {
			CommandType = commandType;
			return this;
		}
		/// <summary>
		/// Add Parameter
		/// </summary>
		/// <param name="parameter"></param>
		/// <exception cref="ArgumentNullException">Throw when parameter is null</exception>
		/// <returns>SqlStatement</returns>
		public SqlStatement AddParameter(QueryParameter parameter) {
			if (parameter == null) throw new ArgumentNullException("parameter");
			Parameters.Add(parameter);
			return this;
		}
		/// <summary>
		/// Parameter in Sql statement
		/// </summary>
		public List<QueryParameter> Parameters { get; private set; }
		/// <summary>
		/// Executes SQL statement against a connection object, implement by call DbCommand.ExecuteNonQuery method
		/// </summary>
		public void ExecuteNonQuery() {
			var contextService = new BaseDbContext.ContextService(DbContext.Instance.Context);
			contextService.Excute(CommandText, Parameters, CommandType);
		}
		/// <summary>
		/// Executes the CommandText against the connection and return the DbDataReader
		/// </summary>
		/// <returns>DbDataReader</returns>
		public DbDataReader ExecuteReader() {
			return ExecuteReader(CommandBehavior.Default);
		}
		/// <summary>
		/// Executes the CommandText against the connection and return the DbDataReader using one of CommandBehavior values
		/// </summary>
		/// <param name="behavior"></param>
		/// <returns></returns>
		public DbDataReader ExecuteReader(CommandBehavior behavior) {
			var contextService = new BaseDbContext.ContextService(DbContext.Instance.Context);
			return contextService.ExcuteReader(CommandText, Parameters, CommandType, behavior);
		}
		/// <summary>
		/// Executes the SQL statement and return first column of first row in the result set returned by the query. All other columns and rows are ignored
		/// </summary>
		/// <returns></returns>
		public object ExecuteScalar() {
			var contextService = new BaseDbContext.ContextService(DbContext.Instance.Context);
			return contextService.ExcuteObj(CommandText, Parameters, CommandType);
		}
	}
}
